/**
 * 线性表的顺序存储
 * 通过内存地址的连续性来显示数据元素间的逻辑关系
 * js可以采用数组来实现连续内存空间的分配（无法采用指针动态分配）
 * 无法采用 c 中的指针来分配空间，所以使用数组来分配空间
 * 
 * 优点：能够随机存取，下标访问速度为O(1)，实现简单
 * 缺点：删除和插入数据需要移动元素，效率较低
 */

 class Sequence {
     /**
      * 初始化线性表
      * @param {Number/Array}} init 
      */
    constructor (init) {
        this.data = Array.isArray(init) ? new Array(...init) : new Array(init) // 分配连续的地址空间
        this.length = this.data.length

        this.RANGE_ERROR = 'range_error'
        this.SUCCESS = 'success'
        this.FATAL = 'FATAL'
        this.FAIL = 'fail'
    }
    /**
     * 根据下标，获取顺序表中的值
     * @param {*} pos 下标
     * @param {*} ele 接收值得变量
     */
    retrieve (pos, ele) {
        let status = this.RANGE_ERROR
        if (pos >= 0 && pos < this.data.length) {
            ele = this.data[pos]
            status = this.SUCCESS
        }
        return status
    }
    /**
     * 根据值，获取下标
     * @param {*} val 进行匹配的值
     * @param {*} pos 接收下标的变量
     */
    locate (val, pos) {
        let status = this.RANGE_ERROR
        for (let i = 0; i < this.data.length; i++) {
            let ele = this.data[i]
            if (ele === val) {
                pos = i
                status = this.SUCCESS
                break
            }
        }
        return status
    }
    /**
     * 在指定的位置插入数据
     * @param {*} pos 需要插入数据的下标
     * @param {*} val 插入的值
     */
    insert (pos, val) {
        let status = this.RANGE_ERROR
        if (pos >= 0 && pos < this.data.length) {
            for (let i = this.data.length - 1; i >= pos; i--) {
                this.data[i + 1] = this.data[i]
            }
            this.data[pos] = val
            this.data.length++
            status = this.SUCCESS
        }
        return status
    }
    /**
     * 删除指定下标的元素
     * @param {*} pos 下标
     */
    remove (pos) {
        let status = this.RANGE_ERROR
        if (pos >= 0 && pos < this.data.length) {
            for (let i = pos; i < this.data.length; i++) {
                this.data[pos] = this.data[pos + 1]
            }
            this.data.length--
            status = this.SUCCESS
        }
        return status
    }
    /**
     * 替换指定下标的元素值
     * @param {*} pos 下标
     * @param {*} val 替换的值
     */
    replace (pos, val) {
        let status = this.RANGE_ERROR
        if (pos >= 0 && pos < this.data.length) {
            this.data[pos] = val
            status = this.SUCCESS
        }
        return status
    }
    destory () {
        this.data = null
        this.data.length = 0
    }
    clear () {
        this.data = []
        this.data.length = 0
    }
    empty () {
        return this.data.length === 0
    }
    /**
     * 求指定下标的前驱
     * @param {*} pos 下标
     * @param {*} ele 接收前驱值的变量
     */
    prior (pos, ele) {
        let status = this.RANGE_ERROR
        if (pos >= 1 && pos < this.data.length) {
            ele = this.data[pos - 1]
            status = this.SUCCESS
        }
        return status
    }
    /**
     * 获取指定下标的后继
     * @param {*} pos 下标
     * @param {*} ele 接收后继值的变量
     */
    next (pos, ele) {
        let status = this.RANGE_ERROR
        if (pos >= 0 && pos < this.data.length - 1) {
            ele = this.data[pos + 1]
            status = this.SUCCESS
        }
        return status
    }
    push (val) {
        this.data[this.data.length + 1] = val
    }
 }



 const a = new Sequence(5)
 a.insert(0, 0)
 a.insert(1, 1)
 console.log(a.data)
 a.remove(1)
 console.log(a.data)